/**
 * Copyright 2019-2020 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FUSION_ENGINE_OPTIMIZER_ADAPTER_ADAPTER_ITF_OP_STORE_ADAPTER_H_
#define FUSION_ENGINE_OPTIMIZER_ADAPTER_ADAPTER_ITF_OP_STORE_ADAPTER_H_

#include <map>
#include <memory>
#include <string>
#include <vector>
#include "graph/node.h"
#include "graph/op_desc.h"
#include "graph/types.h"
#include "graph/utils/attr_utils.h"
#include "graph/utils/node_utils.h"
#include "nlohmann/json.hpp"
#include "ops_store/op_kernel_info.h"
#include "common/op_info_common.h"

namespace fe {
class OpStoreAdapter;
using OpStoreAdapterPtr = std::shared_ptr<OpStoreAdapter>;
using ScopeNodeMap = std::map<int64_t, std::vector<ge::NodePtr>>;
using ScopeNodeIdMap = std::map<int64_t, std::vector<ge::Node *>>;

struct PreCompileNodePara {
  ge::Node *node;
  OpKernelInfoPtr op_kernel_info_ptr;
  std::string imply_type_str;
  std::string op_dsl_file_path;
  std::string session_graph_id;
};

struct CompileInfoParam {
  std::vector<ge::NodePtr> &buff_fus_compile_failed_nodes;
  std::vector<ge::NodePtr> buff_fus_to_del_nodes;
  ScopeNodeIdMap fusion_nodes_map;
  std::map<int64_t, std::string> scope_json_map;
  bool ignore_compile_strategy;
  int64_t minimum_negative_scope;
  explicit CompileInfoParam(std::vector<ge::NodePtr> &buff_fus_compile_failed_nodes_param)
      : buff_fus_compile_failed_nodes(buff_fus_compile_failed_nodes_param),
        ignore_compile_strategy(false),
        minimum_negative_scope(0) {
  }
};

class OpStoreAdapter {
 public:
  virtual ~OpStoreAdapter() {}

  /*
   *  @ingroup fe
   *  @brief   initialize op adapter
   *  @return  SUCCESS or FAILED
   */
  virtual Status Initialize(const std::map<std::string, std::string> &options, const std::string &engine_name) = 0;

  /*
   *  @ingroup fe
   *  @brief   finalize op adapter
   *  @return  SUCCESS or FAILED
   */
  virtual Status Finalize() = 0;

  /*
   *  @ingroup fe
   *  @brief   check op wether supported in ops store
   *  @param   [in] op_desc   infomation of op in ge
   *  @return  true or false
   */
  virtual bool CheckSupport(const ge::OpDesc &op_desc, OpKernelInfoPtr op_kernel_info_ptr, std::string &reason) = 0;

  virtual Status CompileOp(ScopeNodeIdMap &fusion_nodes_map, map<int64_t, std::string> &json_path_map,
                           std::vector<ge::NodePtr> &buff_fus_compile_failed_nodes,
                           const std::vector<ge::NodePtr> &buff_fus_to_del_nodes) = 0;

  virtual Status CompileOp(CompileInfoParam &compile_info) = 0;

  virtual Status PreCompileOp(vector<PreCompileNodePara> &compile_para_vec) = 0;

  virtual Status SelectOpFormat(const ge::OpDesc &op_desc, const OpKernelInfoPtr &op_kernel_info_ptr,
                                const HeavyFormatInfo &heavy_format_info, string &op_format_dtype_str) = 0;

  virtual Status OpBuilder(ge::NodePtr node_ptr) = 0;
};

}  // namespace fe

#endif  // FUSION_ENGINE_OPTIMIZER_ADAPTER_ADAPTER_ITF_OP_STORE_ADAPTER_H_
